<template>
  <div class="notes-page">
    <el-container>
      <el-header class="header">
        <div class="header-content">
          <!-- 正常状态：显示返回按钮、分组选择器、搜索按钮 -->
          <template v-if="!isSearching">
            <el-button @click="$router.push('/dashboard')" icon="ArrowLeft">
              返回
            </el-button>
            <div class="group-selector" @click="toggleGroupModal">
              <span class="group-title">{{ currentGroupTitle }}</span>
              <el-icon><ArrowDown /></el-icon>
            </div>
            <div class="search-section">
              
                <el-button 
                  v-if="selectedNotes.length > 0 && filteredNotes.length > 0" 
                  @click="selectAllNotes" 
                  type="text"
                  class="select-all-btn"
                  :class="{ 'all-selected': isAllSelected }"
                >
                  <el-icon><Select /></el-icon>
                  {{ isAllSelected ? '取消全选' : '全选' }}
                </el-button>
           
                   <!-- <el-tooltip 
                :content="isAllSelected ? '取消全选所有笔记' : '全选所有笔记'"
                placement="bottom"
              >
                <el-button 
                  v-if="selectedNotes.length > 0 && filteredNotes.length > 0" 
                  @click="selectAllNotes" 
                  type="text"
                  class="select-all-btn"
                  :class="{ 'all-selected': isAllSelected }"
                >
                  <el-icon><Select /></el-icon>
                  {{ isAllSelected ? '取消全选' : '全选' }}
                </el-button>
              </el-tooltip> -->
              <el-button 
                v-if="!isSearching && selectedNotes.length === 0" 
                @click="startSearch" 
                type="text"
                class="search-toggle-btn"
              >
                <el-icon><Search /></el-icon>
              </el-button>
            </div>
          </template>
          
          <!-- 搜索状态：显示搜索输入框 -->
          <template v-else>
            <div class="search-full-container">
              <el-input
                v-model="searchKeyword"
                placeholder="搜索笔记..."
                size="large"
                @input="handleSearch"
                ref="searchInput"
                class="search-full-input"
              >
                <template #prefix>
                  <el-icon class="search-icon"><Search /></el-icon>
                </template>
                <template #suffix>
                  <el-button 
                    @click="cancelSearch" 
                    type="text"
                    class="cancel-search-btn"
                  >
                    <el-icon><Close /></el-icon>
                  </el-button>
                </template>
              </el-input>
            </div>
          </template>
        </div>
      </el-header>
      
      <el-main class="main">
        <div class="notes-container">
          <!-- 搜索提示词显示 -->
          <div v-if="searchKeyword && filteredNotes.length > 0" class="search-tip">
            <el-icon class="search-tip-icon"><Search /></el-icon>
            <span class="search-tip-text">找到 {{ filteredNotes.length }} 条相关笔记</span>
          </div>
          
          <div v-if="filteredNotes.length === 0" class="empty-state">
            <el-empty 
              :description="searchKeyword ? '未找到相关笔记' : '暂无笔记'" 
              :image="searchKeyword ? 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg' : undefined"
            >
              <template #description>
                <div class="empty-description">
                  <p v-if="searchKeyword" class="search-empty-text">
                    未找到包含"{{ searchKeyword }}"的笔记
                  </p>
                  <p v-else-if="currentGroup.id !== 'all'" class="group-empty-text">
                    "{{ currentGroup.name }}"分组下暂无笔记
                  </p>
                  <p v-else class="all-empty-text">
                    还没有创建任何笔记
                  </p>
                  <!-- <el-button 
                    v-if="!searchKeyword" 
                    type="primary" 
                    @click="createNote"
                    class="create-note-btn"
                  >
                    <el-icon><Edit /></el-icon>
                    创建第一条笔记
                  </el-button> -->
                </div>
              </template>
            </el-empty>
          </div>
          <div v-else class="notes-list">
            <el-card 
              v-for="note in filteredNotes" 
              :key="note.id"
              class="note-card"
              :class="{ 'selected': selectedNotes.includes(note.id) }"
              @click="handleNoteClick(note, $event)"
              shadow="hover"
            >
              <!-- 选中图标 -->
              <div class="note-select-icon" @click.stop="toggleNoteSelection(note)">
                <el-icon v-if="selectedNotes.includes(note.id)">
                  <Check />
                </el-icon>
                <div v-else class="select-circle"></div>
              </div>
              
              <div class="note-header">
                <h3 class="note-title" v-html="highlightKeyword(note.title)"></h3>
              </div>
              <div class="note-content" v-html="highlightKeyword(note.summary)"></div>
              <div class="note-time note-footer" >{{ formatTime(note.updated_at) }}</div>
              <!-- <div class="note-footer">
                <div class="note-tags">
                  <el-tag v-if="note.group_name" size="small" type="info">
                    {{ note.group_name }}
                  </el-tag>
                  <el-tag v-else size="small" type="warning">未分组</el-tag>
                </div>
              </div> -->
            </el-card>
          </div>
        </div>
        
        <!-- 加载状态指示器 -->
        <div v-if="loading && page > 1" class="loading-indicator">
          <el-skeleton :rows="1" animated />
        </div>
        
        <!-- 没有更多数据提示 -->
        <div v-if="!hasMore && notes.length > 0" class="no-more-data">
          没有更多了 ~
        </div>
        
      </el-main>
    </el-container>
    
    <!-- 回到顶部按钮（与新增按钮大小相同且垂直对称） -->
    <transition name="fade">
      <div 
        v-show="showBackToTop" 
        class="back-to-top"
        @click="scrollToTop"
      >
        <el-icon><ArrowUp /></el-icon>
      </div>
    </transition>
    
    <!-- 悬浮新增按钮 -->
    <div class="fab-button" @click="createNote">
      <el-icon><Edit /></el-icon>
    </div>
    
    <!-- 分组管理弹窗 -->
    <el-dialog
      v-model="showGroupModal"
      title="分组管理"
      width="40%"
      :close-on-click-modal="true"
      class="group-modal"
      center
      append-to-body
    >
      <div class="group-list">
        <div 
          v-for="group in groups" 
          :key="group.id"
          class="group-item"
        >
          <div class="group-info" @click="selectGroup(group)">
            <span class="group-name">{{ group.name }}</span>
            <span class="group-count">({{ group.note_count }})</span>
          </div>
          <div class="group-actions">
            <el-icon v-if="group.id === currentGroup.id" class="current-group-icon"><Check /></el-icon>
            <el-button 
              v-if="group.id !== 'all' && group.id !== 'ungrouped'"
              @click.stop="deleteGroup(group)"
              type="danger" 
              size="small" 
              text
              class="delete-group-btn"
            >
              <el-icon><Delete /></el-icon>
            </el-button>
          </div>
        </div>
      </div>
      
      <template #footer>
        <div class="group-modal-actions">
          <el-button @click="showCreateGroupDialog = true" type="primary">
            新建分组
          </el-button>
          <el-button @click="showGroupModal = false">关闭</el-button>
        </div>
      </template>
    </el-dialog>
    
    <!-- 新建分组对话框 -->
    <el-dialog
      v-model="showCreateGroupDialog"
      title="新建分组"
      width="300px"
      :close-on-click-modal="false"
    >
      <el-input
        v-model="newGroupName"
        placeholder="请输入分组名称"
        @keyup.enter="createGroup"
      />
      <template #footer>
        <el-button @click="showCreateGroupDialog = false">取消</el-button>
        <el-button @click="createGroup" type="primary">确定</el-button>
      </template>
    </el-dialog>
    
    <!-- 底部操作横幅 -->
    <div v-if="selectedNotes.length > 0" class="bottom-actions-banner">
      <div class="banner-content">
        <div class="selected-count">
          已选择 {{ selectedNotes.length }} 条笔记
        </div>
        
        <div class="action-buttons">
          <el-button 
            type="danger" 
            @click="deleteSelectedNotes"
            class="action-button"
            size="small"
          >
            <el-icon><Delete /></el-icon>
            删除
          </el-button>
          
          <el-button 
            type="primary" 
            @click="openGroupChangeDialog"
            class="action-button"
            size="small"
          >
            <el-icon><FolderOpened /></el-icon>
            分组
          </el-button>
          
          <el-button 
            type="info" 
            @click="clearSelection"
            class="action-button"
            size="small"
          >
            <el-icon><Close /></el-icon>
            取消
          </el-button>
        </div>
      </div>
    </div>
    
    <!-- 分组更改对话框 -->
    <el-dialog
      v-model="showGroupChangeDialog"
      title="更改分组"
      width="350px"
      :close-on-click-modal="false"
    >
      <div class="group-change-info">
        <p>已选择 <strong>{{ selectedNotes.length }}</strong> 条笔记</p>
      </div>
      
      <el-form>
        <el-form-item label="选择分组">
          <el-select v-model="newGroupId" placeholder="选择分组" style="width: 100%">
            <el-option label="未分组" :value="null" />
            <el-option 
              v-for="group in groups.filter(g => g.id !== 'all' && g.id !== 'ungrouped')" 
              :key="group.id"
              :label="`${group.name} (${group.note_count}条)`"
              :value="group.id"
            />
          </el-select>
        </el-form-item>
      </el-form>
      
      <template #footer>
        <el-button @click="showGroupChangeDialog = false">取消</el-button>
        <el-button 
          @click="changeSelectedNotesGroup" 
          type="primary"
          :disabled="newGroupId === undefined"
        >
          确定
        </el-button>
      </template>
    </el-dialog>
    

  </div>
</template>

<script setup>
import { onBeforeUnmount,ref, computed, onMounted, onUnmounted, nextTick } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import request from '../utils/request'
import { ArrowDown, Search, Edit, Check, Delete, FolderOpened, Close, Select, ArrowUp } from '@element-plus/icons-vue'

const router = useRouter()
const route = useRoute()

// 数据状态
const notes = ref([])
const groups = ref([])
const currentGroup = ref({ id: 'all', name: '全部笔记' })
const searchKeyword = ref('')
const isSearching = ref(false)

// 分页状态
const page = ref(1)
const hasMore = ref(true)
const loading = ref(false)
const pageSize = 10
const showBackToTop = ref(false) // 控制回到顶部按钮显示

// 状态缓存相关
const scrollPosition = ref(0) // 记录滚动位置
const shouldRestoreState = ref(false) // 是否需要恢复状态

// 弹窗状态
const showGroupModal = ref(false)
const showCreateGroupDialog = ref(false)
const showGroupChangeDialog = ref(false)
const newGroupName = ref('')
const newGroupId = ref(null)

// 多选状态
const selectedNotes = ref([])

// 获取存储的分组状态
const getStoredGroupState = () => {
  try {
    const stored = localStorage.getItem('notes-current-group')
    return stored ? JSON.parse(stored) : null
  } catch (error) {
    return null
  }
}

// 保存分组状态
const saveGroupState = (group) => {
  try {
    localStorage.setItem('notes-current-group', JSON.stringify(group))
  } catch (error) {
    console.error('保存分组状态失败:', error)
  }
}

// 计算属性：现在搜索逻辑在后端实现，这里只进行分组过滤
const filteredNotes = computed(() => {
  let filtered = notes.value
  
  // 非搜索模式下，按分组过滤
  if (!searchKeyword.value.trim() && currentGroup.value.id !== 'all') {
    if (currentGroup.value.id === 'ungrouped') {
      filtered = filtered.filter(note => !note.group_id)
    } else {
      filtered = filtered.filter(note => note.group_id === currentGroup.value.id)
    }
  }
  
  // 按时间倒序排列
  return filtered.sort((a, b) => new Date(b.updated_at) - new Date(a.updated_at))
})

// 计算当前分组标题
const currentGroupTitle = computed(() => {
  // 获取分组名称，默认值为'全部笔记'
  const groupName = currentGroup.value?.name || '全部笔记';
  // 截取前6个字符，超过则显示前6个
  return groupName.length > 6 ? groupName.slice(0, 6) : groupName;
});
// 计算是否全选
const isAllSelected = computed(() => {
  if (filteredNotes.value.length === 0) return false
  const allNoteIds = filteredNotes.value.map(note => note.id)
  return allNoteIds.every(id => selectedNotes.value.includes(id))
})

// 方法
const toggleGroupModal = () => {
  showGroupModal.value = !showGroupModal.value
}

const searchInput = ref(null)

const startSearch = () => {
  isSearching.value = true
  nextTick(() => {
    if (searchInput.value) {
      searchInput.value.focus()
    }
  })
}

const cancelSearch = () => {
  isSearching.value = false
  searchKeyword.value = ''
  // 取消搜索后重置分页并重新加载数据
  resetPagination()
  loadNotes()
}

const handleSearch = () => {
  // 搜索时重置分页状态并重新加载数据
  resetPagination()
  // 搜索时强制重新加载，设置isSearch为true以获取更多结果
  loadNotes(false, true)
}

const selectGroup = (group) => {
  // 切换分组时清除状态缓存，重新请求数据
  clearPageState()
  
  currentGroup.value = group
  showGroupModal.value = false
  saveGroupState(group) // 保存选中状态
  resetPagination()
  loadNotes()
}

const createGroup = async () => {
  if (!newGroupName.value.trim()) {
    ElMessage.warning({ message: '请输入分组名称', duration: 350 })
    return
  }
  
  try {
    const response = await request.post('/notes/groups', {
      name: newGroupName.value.trim()
    })
    ElMessage.success({ message: '分组创建成功', duration: 350 })
    newGroupName.value = ''
    showCreateGroupDialog.value = false
    await loadGroups()
    
    // 如果当前显示的是"全部笔记"且没有选中其他分组，则自动选中新创建的分组
    if (currentGroup.value.id === 'all') {
      const newGroup = response.data.group
      if (newGroup) {
        currentGroup.value = newGroup
        saveGroupState(newGroup)
      }
    }
  } catch (error) {
    ElMessage.error({ message: '创建分组失败', duration: 350 })
  }
}

const deleteGroup = async (group) => {
  if (group.id === 'all' || group.id === 'ungrouped') {
    ElMessage.warning({ message: '系统分组不能删除', duration: 350 })
    return
  }
  
  try {
    // 确认删除
    await ElMessageBox.confirm(
      `确定要删除分组"${group.name}"吗？\n\n⚠️ 这将同时删除该分组下的 ${group.note_count} 条笔记\n⚠️ 此操作不可恢复！`, 
      '确认删除分组', 
      {
        confirmButtonText: '确定删除',
        cancelButtonText: '取消',
        type: 'warning',
        dangerouslyUseHTMLString: true,
        customClass: 'delete-group-confirm'
      }
    )
    
    // 显示加载状态
    const loadingMessage = ElMessage({
      message: `正在删除分组"${group.name}"及其 ${group.note_count} 条笔记...`,
      type: 'info',
      duration: 0
    })
    
    // 删除分组（后端会自动删除该分组下的所有笔记）
    await request.delete(`/notes/groups/${group.id}`)
    
    // 关闭加载消息
    loadingMessage.close()
    
    ElMessage.success({ message: `分组"${group.name}"及其 ${group.note_count} 条笔记删除成功`, duration: 350 })
    
    // 如果当前选中的是被删除的分组，则切换到"全部笔记"
    if (currentGroup.value.id === group.id) {
      currentGroup.value = { id: 'all', name: '全部笔记' }
      saveGroupState(currentGroup.value)
    }
    
    // 重新加载数据
    await loadNotes()
    await loadGroups()
    
  } catch (error) {
    if (error !== 'cancel') {
      console.error('删除分组失败:', error)
      ElMessage.error({ message: '删除分组失败: ' + (error.response?.data?.error || error.message), duration: 350 })
    }
  }
}

const createNote = () => {
  // 根据当前选中的分组来决定新笔记的分组
  let groupId = null
  
  if (currentGroup.value.id !== 'all' && currentGroup.value.id !== 'ungrouped') {
    // 如果当前选中的不是"全部笔记"或"未分组"，则使用当前分组
    groupId = currentGroup.value.id
  }
  // 如果当前选中的是"全部笔记"或"未分组"，则 groupId 保持为 null（未分组）
  
  router.push({
    path: '/notes/new',
    query: { group_id: groupId }
  })
}

const handleNoteClick = (note, event) => {
  // 如果当前有选中的笔记，则处理多选逻辑
  if (selectedNotes.value.length > 0) {
    if (selectedNotes.value.includes(note.id)) {
      // 取消选中
      selectedNotes.value = selectedNotes.value.filter(id => id !== note.id)
    } else {
      // 添加到选中列表
      selectedNotes.value.push(note.id)
    }
  } else {
    // 没有选中笔记时，直接进入详情页
    router.push(`/notes/${note.id}`)
  }
}

// 切换笔记选中状态
const toggleNoteSelection = (note) => {
  if (selectedNotes.value.includes(note.id)) {
    selectedNotes.value = selectedNotes.value.filter(id => id !== note.id)
  } else {
    selectedNotes.value.push(note.id)
  }
}

// 清除选中状态
const clearSelection = () => {
  selectedNotes.value = []
}

// 全选/取消全选笔记
const selectAllNotes = () => {
  const allNoteIds = filteredNotes.value.map(note => note.id)
  
  if (isAllSelected.value) {
    // 如果全部已选中，则取消全选
    selectedNotes.value = []
  } else {
    // 否则全选
    selectedNotes.value = allNoteIds
  }
}

const deleteSelectedNotes = async () => {
  if (selectedNotes.value.length === 0) return
  
  try {
    await ElMessageBox.confirm(`确定要删除选中的 ${selectedNotes.value.length} 条笔记吗？`, '确认删除', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    
    // 批量删除
    for (const noteId of selectedNotes.value) {
      await request.delete(`/notes/${noteId}`)
    }
    
    // 从本地数据中删除选中的笔记，不重新请求数据
    notes.value = notes.value.filter(note => !selectedNotes.value.includes(note.id))
    
    // 更新分组数量统计
    await updateGroupCounts()
    
    ElMessage.success({ message: '笔记删除成功', duration: 350 })
    selectedNotes.value = []
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error({ message: '删除笔记失败', duration: 350 })
    }
  }
}

const openGroupChangeDialog = () => {
  if (selectedNotes.value.length === 0) return
  
  // 检查选中的笔记是否都在同一个分组
  const selectedNoteObjects = notes.value.filter(note => selectedNotes.value.includes(note.id))
  const groupIds = [...new Set(selectedNoteObjects.map(note => note.group_id))]
  
  // 如果所有选中的笔记都在同一个分组，则默认选择该分组
  if (groupIds.length === 1) {
    newGroupId.value = groupIds[0]
  } else {
    newGroupId.value = null
  }
  
  showGroupChangeDialog.value = true
}

const changeSelectedNotesGroup = async () => {
  if (selectedNotes.value.length === 0) return
  
  try {
    // 显示加载状态
    const loadingMessage = ElMessage({
      message: `正在更改 ${selectedNotes.value.length} 条笔记的分组...`,
      type: 'info',
      duration: 0
    })
    
    // 批量更新分组
    let successCount = 0
    let errorCount = 0
    
    for (const noteId of selectedNotes.value) {
      try {
        // 先获取笔记的当前内容
        const noteResponse = await request.get(`/notes/${noteId}`)
        const note = noteResponse.data.note
        
        // 更新笔记，保持内容不变，只更改分组
        await request.put(`/notes/${noteId}`, {
          content: note.content,
          group_id: newGroupId.value
        })
        
        successCount++
      } catch (noteError) {
        console.error(`更新笔记 ${noteId} 失败:`, noteError)
        errorCount++
      }
    }
    
    // 关闭加载消息
    loadingMessage.close()
    
    // 显示结果
    if (errorCount === 0) {
      ElMessage.success({ message: `成功更改 ${successCount} 条笔记的分组`, duration: 350 })
    } else if (successCount > 0) {
      ElMessage.warning({ message: `部分成功：${successCount} 条成功，${errorCount} 条失败`, duration: 350 })
    } else {
      ElMessage.error({ message: '所有笔记分组更改失败', duration: 350 })
    }
    
    selectedNotes.value = []
    showGroupChangeDialog.value = false
    
    // 更新本地数据中的分组信息，不重新请求数据
    await updateGroupCounts()
  } catch (error) {
    console.error('更改分组失败:', error)
    ElMessage.error({ message: '更改分组失败: ' + (error.response?.data?.error || error.message), duration: 350 })
  }
}

const deleteNote = async (note) => {
  try {
    await ElMessageBox.confirm('确定要删除这条笔记吗？', '确认删除', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    })
    
    await request.delete(`/notes/${note.id}`)
    
    // 从本地数据中删除笔记，不重新请求数据
    notes.value = notes.value.filter(n => n.id !== note.id)
    
    // 更新分组数量统计
    await updateGroupCounts()
    
    ElMessage.success({ message: '笔记删除成功', duration: 350 })
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error({ message: '删除笔记失败', duration: 350 })
    }
  }
}

const formatTime = (timestamp) => {
  if (!timestamp) return ''
  
  const now = new Date()
  const noteTime = new Date(timestamp)
  const timeDiff = now - noteTime
  
  const today = new Date(now.getFullYear(), now.getMonth(), now.getDate())
  const yesterday = new Date(today.getTime() - 24 * 60 * 60 * 1000)
  
  if (noteTime >= today) {
    return `今天 ${noteTime.getHours().toString().padStart(2, '0')}:${noteTime.getMinutes().toString().padStart(2, '0')}`
  } else if (noteTime >= yesterday) {
    return `昨天 ${noteTime.getHours().toString().padStart(2, '0')}:${noteTime.getMinutes().toString().padStart(2, '0')}`
  } else {
    return `${noteTime.getFullYear()}-${(noteTime.getMonth() + 1).toString().padStart(2, '0')}-${noteTime.getDate().toString().padStart(2, '0')} ${noteTime.getHours().toString().padStart(2, '0')}:${noteTime.getMinutes().toString().padStart(2, '0')}`
  }
}

const highlightKeyword = (text) => {
  if (!searchKeyword.value.trim() || !text) return text
  
  const keyword = searchKeyword.value
  const regex = new RegExp(`(${keyword})`, 'gi')
  return text.replace(regex, '<mark class="highlight-keyword">$1</mark>')
}

const loadNotes = async (isLoadMore = false, isSearch = false) => {
  if (!isLoadMore) {
    // 首次加载或搜索时重置分页状态
    page.value = 1
    hasMore.value = true
    loading.value = true
  }
  
  try {
    // 准备请求参数
    const params = {
      page: page.value,
      limit: isSearch ? 99999 : pageSize
    }
    
    // 如果不是全部分组且不是未分组，添加分组筛选
    if (currentGroup.value.id !== 'all' && currentGroup.value.id !== 'ungrouped') {
      params.groupId = currentGroup.value.id
    }
    
    // 添加搜索关键词
    if (searchKeyword.value.trim()) {
      params.keyword = searchKeyword.value.trim()
    }
    
    const response = await request.get('/notes', { params })
    
    if (isLoadMore) {
      // 加载更多时追加数据
      notes.value = [...notes.value, ...response.data.notes.map(note => ({
        ...note,
        title: note.content.split('\n')[0] || '无标题',
        summary: note.content.split('\n')[1] || '无内容摘要'
      }))]
    } else {
      // 首次加载或搜索时替换数据
      notes.value = response.data.notes.map(note => ({
        ...note,
        title: note.content.split('\n')[0] || '无标题',
        summary: note.content.split('\n')[1] || '无内容摘要'
      }))
    }
    
    // 更新分页状态
    hasMore.value = response.data.pagination?.hasMore || false
    
    // 笔记加载完成后，更新分组数量统计
    await loadGroups()
  } catch (error) {
    console.error('加载笔记失败:', error)
    ElMessage.error({ message: '加载笔记失败', duration: 350 })
  } finally {
    if (!isLoadMore) {
      loading.value = false
    }
  }
}

// 加载更多笔记
const loadMoreNotes = async () => {
  if (loading.value || !hasMore.value) return
  
  try {
    loading.value = true
    page.value++
    // 调用更新后的loadNotes函数，并传入isLoadMore=true
    await loadNotes(true)
  } catch (error) {
    console.error('加载更多笔记失败:', error)
    page.value-- // 回退页码
  } finally {
    loading.value = false
  }
}

// 滚动监听
const handleScroll = () => {
  const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
  const scrollHeight = document.documentElement.scrollHeight || document.body.scrollHeight
  const clientHeight = document.documentElement.clientHeight || window.innerHeight
  
  // 控制回到顶部按钮显示 - 无论是否在加载或是否有更多数据，都应该更新
  showBackToTop.value = scrollTop > 300
  
  // 只有在非加载状态且有更多数据时才触发加载更多
  if ((loading.value || !hasMore.value)) return
  
  // 距离底部100px时触发加载
  if (scrollTop + clientHeight >= scrollHeight - 100) {
    loadMoreNotes()
  }
}

// 重置分页状态
const resetPagination = () => {
  page.value = 1
  hasMore.value = true
  loading.value = false
}

const loadGroups = async () => {
  try {
    // 发送请求获取所有分组及其完整的笔记数量统计
    const response = await request.get('/notes/groups')
    
    // 创建包含全部笔记和未分组的分组数组
    const allGroups = [
      { id: 'all', name: '全部笔记', note_count: notes.value.length },
      { id: 'ungrouped', name: '未分组', note_count: notes.value.filter(n => !n.group_id).length }
    ]
    
    // 处理自定义分组
    if (response.data.groups && Array.isArray(response.data.groups)) {
      response.data.groups.forEach(group => {
        // 优先使用后端返回的分组数量统计
        // 如果后端没有提供，则基于前端已加载的数据计算
        const localNoteCount = notes.value.filter(note => note.group_id === group.id).length
        allGroups.push({
          ...group,
          note_count: group.note_count !== undefined ? group.note_count : localNoteCount
        })
      })
    }
    
    groups.value = allGroups
    
    // 检查是否有自定义分组（除了全部笔记和未分组）
    const hasCustomGroups = response.data.groups.length > 0
    
    // 如果没有自定义分组，确保显示"全部笔记"
    if (!hasCustomGroups) {
      currentGroup.value = { id: 'all', name: '全部笔记' }
      saveGroupState(currentGroup.value)
    } else {
      // 如果有自定义分组，检查当前分组状态是否有效
      const currentGroupExists = allGroups.find(g => g.id === currentGroup.value.id)
      
      if (!currentGroupExists) {
        // 如果当前分组不存在，检查存储的状态
        const storedGroup = getStoredGroupState()
        if (storedGroup) {
          const storedGroupExists = allGroups.find(g => g.id === storedGroup.id)
          if (storedGroupExists) {
            currentGroup.value = storedGroup
          } else {
            // 如果存储的分组也不存在，默认选择第一个自定义分组
            const firstCustomGroup = response.data.groups[0]
            if (firstCustomGroup) {
              currentGroup.value = firstCustomGroup
              saveGroupState(firstCustomGroup)
            }
          }
        } else {
          // 如果没有存储的状态，默认选择第一个自定义分组
          const firstCustomGroup = response.data.groups[0]
          if (firstCustomGroup) {
            currentGroup.value = firstCustomGroup
            saveGroupState(firstCustomGroup)
          }
        }
      }
      // 如果当前分组存在，保持当前选择不变
    }
  } catch (error) {
    console.error('加载分组失败:', error)
  }
}


onMounted(async () => {
  // 先获取存储的分组状态
  const storedGroup = getStoredGroupState()
  
  // 如果有存储的分组状态，先设置当前分组
  if (storedGroup) {
    currentGroup.value = storedGroup
  }
  
  // 添加滚动事件监听
  window.addEventListener('scroll', handleScroll)
  
  // 检查是否有新笔记需要插入（优先处理新笔记）
  const newNoteData = route.query.newNote
  if (newNoteData) {
    try {
      // console.log("新增笔记成功！！！")
      const newNote = JSON.parse(newNoteData)
      
      // 清除query参数，避免重复插入
      const currentQuery = { ...route.query }
      delete currentQuery.newNote
      router.replace({ path: route.path, query: currentQuery })
      
      // 如果有新笔记，不恢复状态缓存，直接加载数据
      await loadNotes()
      await loadGroups()
      
      // 检查新笔记是否已存在于列表中（避免重复插入）
      const noteExists = notes.value.some(note => note.id === newNote.id)
      if (!noteExists) {
        // 格式化新笔记数据，确保与后端数据格式一致
        const formattedNewNote = {
          ...newNote,
          title: newNote.content?.split('\n')[0] || '无标题',
          summary: newNote.content?.split('\n')[1] || '无内容摘要'
        }
        
        // 将格式化后的新笔记插入到列表首位
        notes.value = [formattedNewNote, ...notes.value]
        // 更新分组数量统计
        await updateGroupCounts()
      }
      
    } catch (error) {
      console.error('解析新笔记数据失败:', error)
      // 如果新笔记处理失败，正常加载数据
      await loadNotes()
      await loadGroups()
    }
  } else {
    // 检查是否需要恢复页面状态（仅在没有新笔记时）
    const shouldRestore = restorePageState()
    
    if (shouldRestore) {
      // 如果成功恢复了状态，设置恢复标志
      shouldRestoreState.value = true
      
      // 恢复滚动位置
      restoreScrollPosition()
      // console.log("恢复页面状态！！！")
      // 加载分组数据（不重新加载笔记数据）
      await loadGroups()
    } else {
      // 如果没有恢复状态，正常加载数据
      await loadNotes()
      await loadGroups()
    }
  }
})

// 组件即将销毁，但 DOM 仍完整存在
onBeforeUnmount(() => {
    window.removeEventListener('scroll', handleScroll)
   
   // 保存页面状态
   savePageState()
  
});

// 组件卸载时移除滚动监听并保存状态
// onUnmounted(() => {
//   window.removeEventListener('scroll', handleScroll)
  
//   // 保存页面状态
//   savePageState()
  
// })

// 滚动到顶部
const scrollToTop = () => {
  window.scrollTo({
    top: 0,
    behavior: 'smooth'
  })
  
  // 立即设置为false，避免按钮继续显示
  showBackToTop.value = false
}

// 状态缓存相关函数
const savePageState = () => {
  // 保存滚动位置
  scrollPosition.value = document.documentElement.scrollTop || document.body.scrollTop
  // console.log("组件卸载！！！")
  // console.log("组件卸载！！！"+scrollPosition.value)
  // 保存页面状态到sessionStorage
  const state = {
    notes: notes.value,
    page: page.value,
    hasMore: hasMore.value,
    currentGroup: currentGroup.value,
    searchKeyword: searchKeyword.value,
    isSearching: isSearching.value,
    scrollPosition: scrollPosition.value
  }
  sessionStorage.setItem('notesPageState', JSON.stringify(state))
}

const restorePageState = () => {
  const savedState = sessionStorage.getItem('notesPageState')
  if (savedState) {
    const state = JSON.parse(savedState)
    
    // 恢复数据状态
    notes.value = state.notes || []
    page.value = state.page || 1
    hasMore.value = state.hasMore !== undefined ? state.hasMore : true
    currentGroup.value = state.currentGroup || { id: 'all', name: '全部笔记' }
    searchKeyword.value = state.searchKeyword || ''
    isSearching.value = state.isSearching !== undefined ? state.isSearching : false
    scrollPosition.value = state.scrollPosition || 0
    
    return true
  }
  return false
}

const clearPageState = () => {
  sessionStorage.removeItem('notesPageState')
}

const restoreScrollPosition = () => {
  // console.log("恢复页面状态！！！"+scrollPosition.value)
  if (scrollPosition.value > 0) {
    // 使用setTimeout确保DOM已经渲染完成
    setTimeout(() => {
      window.scrollTo({
        top: scrollPosition.value,
        behavior: 'auto'
      })
    }, 100)
  }
}

// 更新分组数量统计（不重新请求后端数据）
const updateGroupCounts = async () => {
  try {
    // 基于当前本地数据更新分组计数
    const updatedGroups = [
      { id: 'all', name: '全部笔记', note_count: notes.value.length },
      { id: 'ungrouped', name: '未分组', note_count: notes.value.filter(n => !n.group_id).length }
    ]
    
    // 处理自定义分组
    const customGroups = groups.value.filter(g => g.id !== 'all' && g.id !== 'ungrouped')
    customGroups.forEach(group => {
      const localNoteCount = notes.value.filter(note => note.group_id === group.id).length
      updatedGroups.push({
        ...group,
        note_count: localNoteCount
      })
    })
    
    groups.value = updatedGroups
  } catch (error) {
    console.error('更新分组计数失败:', error)
  }
}
</script>

<style scoped>
.notes-page {
  min-height: 100vh;
  background-color: var(--bg-primary);
}

.header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 0 20px;
}

.header-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  height: 100%;
}

.group-selector {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  padding: 10px 16px;
  border-radius: 8px;
  transition: all 0.3s ease;
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, 0.2);
}

.group-selector:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

.group-title {
  font-size: 16px;
  font-weight: 600;
  color: white;
}

.search-section {
  display: flex;
  align-items: center;
  gap: 8px;
}

.search-section .el-button {
  display: flex;
  align-items: center;
  gap: 4px;
  font-size: 14px;
  font-weight: 500;
  transition: all 0.2s;
}

.search-section .el-button:hover {
  transform: translateY(-1px);
}

/* 返回按钮样式优化 */
.header .el-button {
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: white;
  backdrop-filter: blur(10px);
  transition: all 0.3s ease;
  border-radius: 8px;
  font-weight: 500;
}

.header .el-button:hover {
  background: rgba(255, 255, 255, 0.2);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}

/* 搜索相关样式 */
.search-toggle-btn {
  color: #909399;
  transition: all 0.2s;
  border-radius: 50%;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.search-toggle-btn:hover {
  color: #667eea;
  background-color: rgba(102, 126, 234, 0.1);
  transform: scale(1.05);
}

/* 全屏搜索容器样式 */
.search-full-container {
  width: 100%;
  transition: all 0.3s ease;
  animation: searchFullSlideIn 0.3s ease-out;
}

@keyframes searchFullSlideIn {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.search-full-input {
  border-radius: 12px;
}

.search-full-input .el-input__wrapper {
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
  transition: all 0.3s ease;
  border: 1px solid transparent;
  background-color: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
  height: 48px;
}

.search-full-input .el-input__wrapper:hover {
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
  transform: translateY(-1px);
}

.search-full-input .el-input__wrapper.is-focus {
  box-shadow: 0 6px 24px rgba(102, 126, 234, 0.25);
  border-color: rgba(102, 126, 234, 0.3);
  transform: translateY(-1px);
}

.search-full-input .el-input__prefix {
  color: #909399;
  margin-right: 12px;
}

.search-full-input .search-icon {
  font-size: 18px;
  transition: all 0.2s;
}

.search-full-input .el-input__wrapper.is-focus .search-icon {
  color: #667eea;
}

.search-full-input .el-input__suffix {
  margin-left: 12px;
}

.search-full-input .el-input__suffix .el-button {
  color: #909399;
  transition: all 0.2s;
  border-radius: 50%;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.search-full-input .el-input__suffix .el-button:hover {
  color: #f56c6c;
  background-color: rgba(245, 108, 108, 0.1);
  transform: scale(1.1);
}

/* 原有搜索输入框样式保留用于其他场景 */
.search-input-container {
  width: 280px;
  transition: all 0.3s ease;
}

.search-input {
  border-radius: 24px;
}

.search-input .el-input__wrapper {
  border-radius: 24px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.08);
  transition: all 0.3s ease;
  border: 1px solid transparent;
  background-color: rgba(255, 255, 255, 0.95);
  backdrop-filter: blur(10px);
}

.search-input .el-input__wrapper:hover {
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  transform: translateY(-1px);
}

.search-input .el-input__wrapper.is-focus {
  box-shadow: 0 4px 20px rgba(102, 126, 234, 0.25);
  border-color: rgba(102, 126, 234, 0.3);
  transform: translateY(-1px);
}

.search-input .el-input__prefix {
  color: #909399;
  margin-right: 8px;
}

.search-icon {
  font-size: 16px;
  transition: all 0.2s;
}

.search-input .el-input__wrapper.is-focus .search-icon {
  color: #667eea;
}

.search-input .el-input__suffix {
  margin-left: 8px;
}

.search-input .el-input__suffix .el-button {
  color: #909399;
  transition: all 0.2s;
  border-radius: 50%;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.search-input .el-input__suffix .el-button:hover {
  color: #f56c6c;
  background-color: rgba(245, 108, 108, 0.1);
  transform: scale(1.1);
}

.cancel-search-btn {
  color: #909399;
  transition: all 0.2s;
  border-radius: 50%;
  width: 24px;
  height: 24px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.cancel-search-btn:hover {
  color: #f56c6c;
  background-color: rgba(245, 108, 108, 0.1);
}

/* 全选按钮样式优化 */
.select-all-btn {
  color: #667eea;
  font-weight: 600;
  transition: all 0.3s ease;
  border-radius: 8px;
  padding: 8px 16px;
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
  border: 1px solid rgba(102, 126, 234, 0.2);
  backdrop-filter: blur(10px);
}

.select-all-btn:hover {
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.15) 0%, rgba(118, 75, 162, 0.15) 100%);
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.2);
}

.select-all-btn.all-selected {
  color: #f56c6c;
  background: linear-gradient(135deg, rgba(245, 108, 108, 0.1) 0%, rgba(230, 162, 60, 0.1) 100%);
  border-color: rgba(245, 108, 108, 0.2);
}

.select-all-btn.all-selected:hover {
  background: linear-gradient(135deg, rgba(245, 108, 108, 0.15) 0%, rgba(230, 162, 60, 0.15) 100%);
  box-shadow: 0 4px 12px rgba(245, 108, 108, 0.2);
}

/* 原有的搜索容器样式已在上方重新定义 */

.main {
  padding: 20px;
}

.notes-container {
  max-width: 800px;
  margin: 0 auto;
}

.empty-state {
  text-align: center;
  padding: 60px 20px;
}

.empty-description {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
}

.search-empty-text {
  color: var(--text-secondary);
  font-size: 14px;
  margin: 0;
  padding: 12px 20px;
  background: linear-gradient(135deg, rgba(245, 108, 108, 0.05) 0%, rgba(230, 162, 60, 0.05) 100%);
  border: 1px solid rgba(245, 108, 108, 0.15);
  border-radius: 12px;
  backdrop-filter: blur(10px);
}

.group-empty-text {
  color: var(--text-secondary);
  font-size: 14px;
  margin: 0;
  padding: 12px 20px;
  background: linear-gradient(135deg, rgba(64, 158, 255, 0.05) 0%, rgba(100, 108, 255, 0.05) 100%);
  border: 1px solid rgba(64, 158, 255, 0.15);
  border-radius: 12px;
  backdrop-filter: blur(10px);
}

.all-empty-text {
  color: var(--text-secondary);
  font-size: 14px;
  margin: 0;
  padding: 12px 20px;
  background: linear-gradient(135deg, rgba(103, 194, 58, 0.05) 0%, rgba(144, 147, 153, 0.05) 100%);
  border: 1px solid rgba(103, 194, 58, 0.15);
  border-radius: 12px;
  backdrop-filter: blur(10px);
}

.create-note-btn {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 12px 24px;
  border-radius: 12px;
  font-weight: 600;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  border: none;
  box-shadow: 0 4px 16px rgba(102, 126, 234, 0.3);
  transition: all 0.3s ease;
}

.create-note-btn:hover {
  transform: translateY(-2px);
  box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
  background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
}

.create-note-btn .el-icon {
  font-size: 16px;
}

.notes-list {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* 笔记卡片样式优化 */
.note-card {
  cursor: pointer;
  transition: all 0.3s ease;
  background-color: var(--bg-card);
  border-color: var(--border-color);
  position: relative;
  border-radius: 12px;
  overflow: hidden;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.06);
}

.note-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
  border-color: rgba(102, 126, 234, 0.2);
}

.note-card.selected {
  border: 2px solid #667eea;
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.05) 0%, rgba(118, 75, 162, 0.05) 100%);
  transform: translateY(-4px);
  box-shadow: 0 8px 24px rgba(102, 126, 234, 0.15);
}

/* 选中图标样式优化 */
.note-select-icon {
  position: absolute;
  top: 12px;
  right: 12px;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  z-index: 10;
  background: rgba(255, 255, 255, 0.9);
  border-radius: 50%;
  backdrop-filter: blur(10px);
  transition: all 0.3s ease;
}

.select-circle {
  width: 20px;
  height: 20px;
  border: 2px solid #dcdfe6;
  border-radius: 50%;
  background-color: transparent;
  transition: all 0.3s ease;
}

.note-card:hover .select-circle {
  border-color: #667eea;
  transform: scale(1.1);
}

.note-card.selected .select-circle {
  border-color: #667eea;
  background-color: #667eea;
}

.note-select-icon .el-icon {
  color: white;
  font-size: 16px;
  animation: checkIconPop 0.3s ease-out;
}

@keyframes checkIconPop {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.2);
  }
  100% {
    transform: scale(1);
  }
}

.note-header {
  margin-bottom: 12px;
  padding-right: 40px;
}

.note-title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary);
  line-height: 1.4;
  transition: color 0.2s ease;
}

.note-card:hover .note-title {
  color: #667eea;
}

.note-time {
  font-size: 12px;
  color: var(--text-muted);
  margin-top: 8px;
  text-align: right;
  font-weight: 500;
}

.note-content {
  color: var(--text-secondary);
  font-size: 14px;
  line-height: 1.6;
  margin-bottom: 12px;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.note-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border-color);
}

.note-tags {
  display: flex;
  gap: 8px;
}

/* 分组标签样式优化 */
.note-tags .el-tag {
  border-radius: 6px;
  font-weight: 500;
  transition: all 0.2s ease;
  border: none;
}

.note-tags .el-tag--info {
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
  color: #667eea;
}

.note-tags .el-tag--warning {
  background: linear-gradient(135deg, rgba(230, 162, 60, 0.1) 0%, rgba(245, 108, 108, 0.1) 100%);
  color: #e6a23c;
}

.note-tags .el-tag:hover {
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

/* 悬浮按钮 */
.fab-button {
  position: fixed;
  bottom: 80px;
  right: 20px;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
  transition: all 0.3s ease;
  z-index: 1000;
  border: none;
}

.fab-button:hover {
  transform: scale(1.1) translateY(-2px);
  box-shadow: 0 8px 24px rgba(102, 126, 234, 0.6);
  background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
}

.fab-button:active {
  transform: scale(0.95);
}

.fab-button .el-icon {
  font-size: 24px;
  animation: fabIconFloat 2s ease-in-out infinite;
}

/* 回到顶部按钮样式（与新增按钮大小相同且垂直对称） */
.back-to-top {
  position: fixed;
  right: 20px;
  bottom: 150px; /* 精确计算与新增按钮的间距 */
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: 0 6px 20px rgba(102, 126, 234, 0.4);
  transition: all 0.3s ease;
  z-index: 999;
  border: none;
  /* 确保在移动设备上也能正确显示 */
  -webkit-tap-highlight-color: transparent;
  touch-action: manipulation;
}

.back-to-top:hover {
  transform: scale(1.1) translateY(-2px);
  box-shadow: 0 8px 24px rgba(102, 126, 234, 0.6);
  background: linear-gradient(135deg, #5a6fd8 0%, #6a4190 100%);
}

.back-to-top:active {
  transform: scale(0.95);
}

.back-to-top .el-icon {
  font-size: 24px;
  animation: fabIconFloat 2s ease-in-out infinite;
}

/* 确保在所有设备上两个按钮大小一致且垂直对称 */
@media screen and (max-width: 768px) {
  .back-to-top {
    right: 16px;
    bottom: 146px;
    width: 56px !important;
    height: 56px !important;
  }
  
  .fab-button {
    right: 16px !important;
    bottom: 80px !important;
    width: 56px !important;
    height: 56px !important;
  }
}

/* 加载指示器样式 */
.loading-indicator {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 20px;
  color: #667eea;
  font-size: 14px;
}

.loading-icon {
  margin-right: 8px;
  font-size: 16px;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

/* 无更多数据指示器样式 */
.no-more-indicator {
  text-align: center;
  padding: 20px;
  color: #909399;
  font-size: 14px;
  border-top: 1px solid #ebeef5;
}

@keyframes fabIconFloat {
  0%, 100% {
    transform: translateY(0);
  }
  50% {
    transform: translateY(-2px);
  }
}

/* 当有选中笔记时，调整悬浮按钮位置 */
.bottom-actions-banner ~ .fab-button {
  bottom: 120px;
}

/* 分组弹窗样式优化 */
.group-modal ::v-deep .el-dialog {
  border-radius: 16px;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.15);
  overflow: hidden;
}

.group-modal ::v-deep .el-dialog__header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  padding: 20px 24px;
  margin: 0;
}

.group-modal ::v-deep .el-dialog__title {
  color: white;
  font-weight: 600;
  font-size: 18px;
}

.group-modal ::v-deep .el-dialog__headerbtn .el-dialog__close {
  color: white;
  font-size: 20px;
}

.group-modal ::v-deep .el-dialog__body {
  padding: 24px;
  background-color: var(--bg-primary);
}

.group-list {
  max-height: 400px;
  overflow-y: auto;
  border-radius: 8px;
  background-color: var(--bg-card);
  border: 1px solid var(--border-color);
}

.group-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 16px 20px;
  border-bottom: 1px solid var(--border-color);
  transition: all 0.2s ease;
  cursor: pointer;
}

.group-item:hover {
  background-color: var(--hover-bg);
  transform: translateX(4px);
}

.group-item:last-child {
  border-bottom: none;
}

.group-info {
  display: flex;
  align-items: center;
  gap: 8px;
  cursor: pointer;
  flex: 1;
  padding: 8px;
  border-radius: 8px;
  transition: all 0.2s ease;
}

.group-info:hover {
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
}

.group-name {
  font-size: 16px;
  font-weight: 600;
  color: var(--text-primary);
}

.group-count {
  font-size: 14px;
  color: var(--text-muted);
  background-color: var(--bg-primary);
  padding: 2px 8px;
  border-radius: 12px;
  font-weight: 500;
}

.group-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

.current-group-icon {
  color: #667eea;
  font-size: 20px;
  animation: currentGroupPulse 2s infinite;
}

@keyframes currentGroupPulse {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.1);
  }
}

.delete-group-btn {
  opacity: 0;
  transition: all 0.2s ease;
  border-radius: 50%;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.group-item:hover .delete-group-btn {
  opacity: 1;
  transform: scale(1.1);
}

.delete-group-btn:hover {
  background: linear-gradient(135deg, rgba(245, 108, 108, 0.1) 0%, rgba(230, 162, 60, 0.1) 100%);
  color: #f56c6c;
  transform: scale(1.2);
}

.group-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  padding: 20px 24px;
  background-color: var(--bg-card);
  border-top: 1px solid var(--border-color);
}

/* 新建分组对话框样式优化 */
.group-modal ::v-deep .el-dialog--small {
  border-radius: 12px;
}

.group-modal ::v-deep .el-dialog__header {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}

/* 底部操作横幅样式优化 */
.bottom-actions-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  background: linear-gradient(135deg, rgba(255, 255, 255, 0.95) 0%, rgba(248, 249, 250, 0.95) 100%);
  border-top: 1px solid var(--border-color);
  box-shadow: 0 -4px 16px rgba(0, 0, 0, 0.1);
  z-index: 1000;
  padding: 16px 20px;
  backdrop-filter: blur(20px);
}

.dark-theme .bottom-actions-banner {
  background: linear-gradient(135deg, rgba(45, 45, 45, 0.95) 0%, rgba(58, 58, 58, 0.95) 100%);
}

.banner-content {
  display: flex;
  justify-content: space-between;
  align-items: center;
  max-width: 800px;
  margin: 0 auto;
}

.selected-count {
  font-size: 14px;
  font-weight: 600;
  color: var(--text-primary);
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
  padding: 8px 16px;
  border-radius: 20px;
  border: 1px solid rgba(102, 126, 234, 0.2);
}

.action-buttons {
  display: flex;
  gap: 8px;
}

.action-button {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 70px;
  border-radius: 8px;
  font-weight: 500;
  transition: all 0.2s ease;
}

.action-button:hover {
  transform: translateY(-2px);
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}

/* 分组更改对话框样式优化 */
.group-change-info {
  margin-bottom: 20px;
  padding: 16px;
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.05) 0%, rgba(118, 75, 162, 0.05) 100%);
  border-radius: 12px;
  text-align: center;
  border: 1px solid rgba(102, 126, 234, 0.15);
}

.group-change-info p {
  margin: 0;
  color: var(--text-secondary);
  font-size: 14px;
}

.group-change-info strong {
  color: var(--text-primary);
  font-weight: 600;
  font-size: 16px;
}

/* 删除分组确认对话框样式优化 */
.delete-group-confirm ::v-deep .el-message-box {
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.15);
}

.delete-group-confirm ::v-deep .el-message-box__header {
  background: linear-gradient(135deg, #f56c6c 0%, #e6a23c 100%);
  color: white;
  padding: 20px 24px;
  margin: 0;
}

.delete-group-confirm ::v-deep .el-message-box__title {
  color: white;
  font-weight: 600;
  font-size: 18px;
}

.delete-group-confirm ::v-deep .el-message-box__headerbtn .el-message-box__close {
  color: white;
  font-size: 20px;
}

.delete-group-confirm ::v-deep .el-message-box__content {
  padding: 24px;
  background-color: var(--bg-primary);
}

.delete-group-confirm ::v-deep .el-message-box__message {
  line-height: 1.6;
  font-size: 14px;
  color: var(--text-primary);
}

.delete-group-confirm ::v-deep .el-message-box__message p {
  margin: 8px 0;
}

.delete-group-confirm ::v-deep .el-message-box__btns {
  padding: 16px 24px;
  background-color: var(--bg-card);
  border-top: 1px solid var(--border-color);
}

/* 移动端适配 */
@media (max-width: 768px) {
  html.app-5plus .header {
    padding-top: var(--status-bar-height);
    height: calc(55px + var(--status-bar-height));
  }
  
  .header-content {
    flex-direction: row;
    padding: 10px 0;
    justify-content: space-between;
    align-items: center;
    position: relative;
  }
  
  /* 移动端分组选择器居中 */
  .header-content .group-selector {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
    z-index: 10;
    background: rgba(255, 255, 255, 0.15);
    backdrop-filter: blur(15px);
    border: 1px solid rgba(255, 255, 255, 0.3);
    box-shadow: 0 4px 16px rgba(0, 0, 0, 0.1);
  }
  
  .group-selector {
    padding: 8px 16px;
    min-width: 90px;
    text-align: center;
    border-radius: 12px;
  }
  
  .group-title {
    font-size: 15px;
    font-weight: 600;
    color: white;
    text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
  }
  
  .search-input-container {
    width: 200px;
  }
  
  .search-input .el-input__wrapper {
    border-radius: 20px;
  }
  
  .search-toggle-btn {
    width: 36px;
    height: 36px;
    border-radius: 50%;
    display: flex;
    align-items: center;
    justify-content: center;
  }
  
  /* 移动端返回按钮样式 */
  .header .el-button {
    min-width: 60px;
    height: 36px;
    border-radius: 8px;
    font-size: 14px;
  }
  
  /* 移动端全屏搜索适配 */
  .search-full-input .el-input__wrapper {
    height: 44px;
    border-radius: 10px;
  }
  
  .search-full-input .search-icon {
    font-size: 16px;
  }
  
  .search-full-input .el-input__suffix .el-button {
    width: 28px;
    height: 28px;
  }
  
  .main {
    padding: 1px;
  }
  
  .notes-list {
    gap: 1px;
  }
  
  .note-card {
    padding: 1px;
  }
  
  .note-title {
    font-size: 15px;
  }
  
  .note-content {
    font-size: 13px;
  }
  
  .fab-button {
    bottom: 70px;
    right: 15px;
    width: 50px;
    height: 50px;
  }
  
  .fab-button .el-icon {
    font-size: 20px;
  }
  
  .group-modal ::v-deep .el-dialog {
    width: 95% !important;

  }
  
  .note-dialog ::v-deep .el-dialog {
    width: 95% !important;
     
  }
  
  .note-select-icon {
    top: 8px;
    right: 8px;
    width: 24px;
    height: 24px;
  }
  
  .select-circle {
    width: 18px;
    height: 18px;
  }
  
  .note-header {
    padding-right: 30px;
  }
  
  /* 移动端底部横幅适配 */
  .bottom-actions-banner {
    padding: 12px 15px;
  }
  
  .banner-content {
    gap: 10px;
  }
  
  .selected-count {
    font-size: 13px;
    padding: 6px 12px;
  }
  
  .action-buttons {
    gap: 6px;
  }
  
  .action-button {
    min-width: 60px;
    font-size: 12px;
    padding: 6px 12px;
  }
  
  /* 移动端悬浮按钮位置调整 */
  .bottom-actions-banner ~ .fab-button {
    bottom: 100px;
  }
  
  /* 移动端搜索提示词适配 */
  .search-tip {
    margin-bottom: 16px;
    padding: 12px 16px;
    font-size: 13px;
  }
  
  /* 移动端空状态适配 */
  .empty-state {
    padding: 40px 15px;
  }
  
  .search-empty-text,
  .group-empty-text,
  .all-empty-text {
    font-size: 13px;
    padding: 10px 16px;
  }
  
  .create-note-btn {
    padding: 10px 20px;
    font-size: 14px;
  }
  
  .create-note-btn .el-icon {
    font-size: 14px;
  }
  
  .search-tip-icon {
    font-size: 18px;
  }
  
  /* 移动端分组弹窗适配 */
  .group-item {
    padding: 12px 16px;
  }
  
  .group-name {
    font-size: 15px;
  }
  
  .group-count {
    font-size: 12px;
    padding: 1px 6px;
  }
}

/* 搜索提示词样式 */
.search-tip {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 20px;
  padding: 14px 18px;
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.05) 0%, rgba(118, 75, 162, 0.05) 100%);
  border: 1px solid rgba(102, 126, 234, 0.15);
  border-radius: 12px;
  box-shadow: 0 4px 12px rgba(102, 126, 234, 0.08);
  color: var(--text-primary);
  font-size: 14px;
  font-weight: 500;
  backdrop-filter: blur(10px);
  animation: searchTipFadeIn 0.3s ease-out;
}

@keyframes searchTipFadeIn {
  from {
    opacity: 0;
    transform: translateY(-10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

.search-tip-icon {
  color: #667eea;
  font-size: 20px;
  animation: searchIconPulse 2s infinite;
}

@keyframes searchIconPulse {
  0%, 100% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.1);
  }
}

.search-tip-text {
  color: var(--text-primary);
  font-weight: 600;
}

/* 高亮关键词样式 */
:deep(.highlight-keyword) {
  background: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%);
  color: #333;
  padding: 2px 4px;
  border-radius: 4px;
  font-weight: 600;
  box-shadow: 0 1px 3px rgba(255, 215, 0, 0.3);
  animation: highlightPulse 1.5s ease-in-out infinite alternate;
}

@keyframes highlightPulse {
  from {
    box-shadow: 0 1px 3px rgba(255, 215, 0, 0.3);
  }
  to {
    box-shadow: 0 2px 6px rgba(255, 215, 0, 0.5);
  }
}

/* 深色主题适配 */
.dark-theme :deep(.highlight-keyword) {
  background: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%);
  color: #333;
}

.dark-theme .note-card {
  background-color: var(--bg-card);
  border-color: var(--border-color);
}

.dark-theme .note-card:hover {
  border-color: rgba(102, 126, 234, 0.3);
}

.dark-theme .note-card.selected {
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.1) 0%, rgba(118, 75, 162, 0.1) 100%);
}

.dark-theme .note-select-icon {
  background: rgba(45, 45, 45, 0.9);
}

.dark-theme .group-list {
  background-color: var(--bg-card);
  border-color: var(--border-color);
}

.dark-theme .group-item:hover {
  background-color: var(--hover-bg);
}

.dark-theme .group-info:hover {
  background: linear-gradient(135deg, rgba(102, 126, 234, 0.15) 0%, rgba(118, 75, 162, 0.15) 100%);
}

.dark-theme .group-count {
  background-color: var(--bg-primary);
  color: var(--text-muted);
}

/* 深色主题全屏搜索适配 */
.dark-theme .search-full-input .el-input__wrapper {
  background-color: rgba(45, 45, 45, 0.95);
  border-color: var(--border-color);
}

.dark-theme .search-full-input .el-input__wrapper:hover {
  background-color: rgba(58, 58, 58, 0.95);
}

.dark-theme .search-full-input .el-input__wrapper.is-focus {
  background-color: rgba(58, 58, 58, 0.95);
  border-color: rgba(102, 126, 234, 0.3);
}

/* 加载指示器样式 */
.loading-indicator {
  padding: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
}

/* 没有更多数据提示样式 */
.no-more-data {
  text-align: center;
  padding: 10px;
  /* color: #909399; */
  font-size: 14px;
  /* background: linear-gradient(135deg, rgba(144, 147, 153, 0.05) 0%, rgba(255, 255, 255, 0.1) 100%); */
  /* border-radius: 12px; */
  margin: 10px;
}



/* 动画效果 */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.3s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

/* 深色主题适配 */
.dark-theme .no-more-data {
  color: #bbb;
  /* background: linear-gradient(135deg, rgba(144, 147, 153, 0.05) 0%, rgba(20, 20, 20, 0.2) 100%); */
}

/* 深色主题加载指示器适配 */
.dark-theme .loading-indicator ::v-deep .el-skeleton__item {
  background: linear-gradient(90deg, #2a2a2a 25%, #3a3a3a 50%, #2a2a2a 75%);
  background-size: 400% 100%;
  animation: skeleton-loading-dark 1.5s ease-in-out infinite;
}

@keyframes skeleton-loading-dark {
  0% {
    background-position: 100% 50%;
  }
  100% {
    background-position: 0 50%;
  }
}

  /* 移动端弹窗宽度 */
  @media (max-width: 768px) {
    /* 确保所有弹窗在移动端宽度为95% */
    .el-dialog {
      width: 90% !important;
      max-width: 100% !important;
      margin: 10px auto !important;
      --el-dialog-width: 90% !important;
    }
    }
</style>
<style>
  /* 默认弹窗宽度 */
  .el-dialog {
    --el-dialog-width: 40% !important;
    max-width: 100% !important;
  }

  /* 移动端弹窗宽度 */
  @media (max-width: 768px) {
    /* 确保所有弹窗在移动端宽度为95% */
    .el-dialog {
      width: 80% !important;
      max-width: 100% !important;
      margin: 20px auto !important;
      --el-dialog-width: 90% !important;
         /* 移动端弹窗往下挪40px */
      margin-top: 100px !important;
    }
    /* 为append-to-body的弹窗额外添加规则 */
    .el-dialog.group-modal {
      width: 90% !important;
      max-width: 100% !important;
      margin: 10px auto !important;
      --el-dialog-width: 90% !important;
      /* 移动端弹窗往下挪40px */
      margin-top: 90px !important;
    }
  }
</style>


